package com.tyut.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyut.config.UserException;
import com.tyut.entity.Files;
import com.tyut.entity.Merchant;
import com.tyut.entity.User;
import com.tyut.mapper.MerchantMapper;
import com.tyut.mapper.UserMapper;
import com.tyut.service.FilesService;
import com.tyut.service.MerchantService;
import com.tyut.service.UserService;
import com.tyut.util.JwtUtil;
import com.tyut.vo.ResultJson;
import io.micrometer.common.util.StringUtils;
import io.minio.errors.*;
import jakarta.annotation.Resource;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 李嘉昕
 * @since 2025-03-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    PasswordEncoder passwordEncoder; // 注入密码加密器

    @Resource
    FilesService filesService;  // 注入文件记录服务

    @Resource
    MerchantService merchantService;  // 注入商家服务


    @Override
    public IPage<User> list(Integer pageNo, Integer pageSize, String username , Integer role) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("role", role);
        if (StringUtils.isNotBlank(username)) {
            wrapper.like("username", username);
        }
        return page(new Page<>(pageNo, pageSize), wrapper);
    }


    @Override
    public boolean check(String fieldName, String value, Integer id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq(fieldName, value); // 查询

        // 如果id不为空，则排除当前用户
        if (id != null) {
            wrapper.ne("id", id);
        }
        return this.count(wrapper) == 0;
    }

    @Override
    public String login(String username, String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //按照用户名查询用户
        wrapper.eq("username", username);
        User user = this.getOne(wrapper);
        //如果员工对象为空，说明没有查询到用户
        //如果能查询到用户，则判断密码是否正确
        if (user == null ||!passwordEncoder.matches(password, user.getPassword())) {
            throw new UserException("用户名或密码错误");
        }
        //如果active为 0，说明用户被禁用,无法登录
        if (!user.getActive()) {
            throw new UserException("该账号被禁用");
        }
        return JwtUtil.create(user);
    }

    @Override
    public boolean register(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername())
                .or()
                .eq("email", user.getEmail())
                .or()
                .eq("phone", user.getPhone());

        User existingUser = this.getOne(wrapper);
        if (existingUser != null) {
            if (user.getUsername().equals(existingUser.getUsername())) {
                throw new UserException("用户名已存在");
            }
            if (user.getPhone().equals(existingUser.getPhone())) {
                throw new UserException("手机号已被注册");
            }
            if (user.getEmail().equals(existingUser.getEmail())) {
                throw new UserException("邮箱已被注册");
            }
        }
        return this.save(user);
    }

    @Override
    public boolean forget(String username , String phone, String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //按照用户名查询用户
        wrapper.eq("username", username);
        User user = this.getOne(wrapper);

        //如果员工对象为空，说明没有查询到用户
        if (user == null) {
            throw new UserException("该用户不存在");
        }
        //如果手机号不正确，则不允许修改
        if (!user.getPhone().equals(phone)) {
            throw new UserException("手机号不正确");
        }
        //如果密码相同，则不允许修改
        if (passwordEncoder.matches(password, user.getPassword())) {
            throw new UserException("新密码与旧密码不能相同");
        }else {
            user.setPassword(passwordEncoder.encode(password));
            return this.updateById(user);
        }
    }

    @Override
    public List<User> getActive() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("active", 1);
        return this.list(wrapper);
    }

    @Override
    public User getUserMessage(Integer sessionId) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id", sessionId);
        return this.getOne(wrapper);
    }

    @Override
    public String updateIcon(MultipartFile file, Integer id) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        User user = this.getById(id);
        String oldIcon = user.getIcon();
        if (user.getIcon().equals("")) {
            System.out.println("当前是默认头像");
            oldIcon = "default";
        }

        if (null != file) {
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("icon", oldIcon);
            Long count = this.count(wrapper);
            user.setIcon(filesService.fileUpload("gaming", file , count , oldIcon));
        }
        this.updateById(user);

        User newUser = this.getById(id);
        System.out.println("更新后的头像名称为：" + newUser.getIcon());

        return newUser.getIcon();
    }

    @Override
    public boolean updateUsername(String username, Integer id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username)
                .ne("id", id);
        if (this.count(wrapper) != 0) {
            throw new UserException("用户名已存在");
        }
        wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        User user = this.getOne(wrapper);
        if (user.getUsername().equals(username)) {
            throw new UserException("用户名未改变");
        }

        user.setUsername(username);
        return this.updateById(user);
    }

    @Override
    public boolean updatePassword(String oldPsw , String newPsw, Integer id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        User user = this.getOne(wrapper);
        if (!passwordEncoder.matches(oldPsw, user.getPassword())) {
            throw new UserException("请输入正确的旧密码");
        }
        if (passwordEncoder.matches(newPsw, user.getPassword())) {
            throw new UserException("新密码与旧密码不能相同");
        }
        user.setPassword(passwordEncoder.encode(newPsw));
        return this.updateById(user);
    }

    @Override
    public boolean updatePhone(String phone, Integer id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone)
                .ne("id", id);
        if (this.count(wrapper) != 0) {
            throw new UserException("手机号已被注册");
        }
        wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        User user = this.getOne(wrapper);
        if (user.getPhone().equals(phone)) {
            throw new UserException("手机号未改变");
        }
        user.setPhone(phone);
        return this.updateById(user);
    }

    @Override
    public boolean updateEmail(String email, Integer id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("email", email)
                .ne("id", id);
        if (this.count(wrapper) != 0) {
            throw new UserException("邮箱已被注册");
        }
        wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        User user = this.getOne(wrapper);
        if (user.getEmail().equals(email)) {
            throw new UserException("邮箱未改变");
        }
        user.setEmail(email);

        return this.updateById(user);
    }

    @Override
    public IPage<User> getApply(Integer pageNo, Integer pageSize) {
        QueryWrapper<Merchant> merWrapper = new QueryWrapper<>();
        merWrapper.select("user_id").eq("status", 0);

        List<Object> userIds = merchantService.listObjs(merWrapper);
        if (userIds.size() == 0) {
            return null;
        }
        Page<User> page = new Page<>(pageNo, pageSize);
        QueryWrapper<User> userWrapper = new QueryWrapper<>();
        userWrapper.in("id", userIds);
        return this.page(page, userWrapper);
    }
}
